package com.gsi.webstore.platform.storefront.pipelet;

import java.math.BigDecimal;
import java.util.Iterator;

import com.intershop.beehive.bts.capi.orderprocess.ProductLineItem;
import com.intershop.beehive.bts.capi.orderprocess.basket.Basket;
import com.intershop.beehive.bts.capi.orderprocess.basket.BasketMgr;
import com.intershop.beehive.core.capi.common.SystemException;
import com.intershop.beehive.core.capi.naming.NamingMgr;
import com.intershop.beehive.core.capi.pipeline.Pipelet;
import com.intershop.beehive.core.capi.pipeline.PipeletExecutionException;
import com.intershop.beehive.core.capi.pipeline.PipelineDictionary;
import com.intershop.beehive.core.capi.pipeline.PipelineInitializationException;
import com.intershop.beehive.foundation.quantity.Quantity;

/**
 * 
 */
public class RemoveAndUpdatePLIQuantity extends Pipelet
{
    /**
     * Constant used to access the pipeline dictionary with key 'Cart'
     */
    public static final String DN_CART = "Cart";
    
    /**
     * Constant used to access the pipeline dictionary with key 'UpdatedCart'
     */
    public static final String DN_UPDATED_CART = "UpdatedCart";
    
    /**
     * Constant used to access the pipeline dictionary with key 'CartBO'
     */
    public static final String DN_CART_BO = "CartBO";
    
    /**
     * Constant used to access the pipeline dictionary with key
     * 'ProductLineItem'
     */
    public static final String DN_PRODUCT_LINE_ITEM = "ProductLineItem";
    
    private BasketMgr basketMgr;
    private String storeFrontIdAttribute = "STORE_ID";

    public void init() 
        throws PipelineInitializationException, SystemException
    {
        super.init();
        basketMgr = (BasketMgr)NamingMgr.getInstance().lookupManager("BasketMgr");
    }

    /**
     * The pipelet's execute method is called whenever the pipelets gets
     * executed in the context of a pipeline and a request. The pipeline
     * dictionary valid for the currently executing thread is provided as a
     * parameter.
     * 
     * @param dict
     *            The pipeline dictionary to be used.
     * @throws PipeletExecutionException
     *             Thrown in case of severe errors that make the pipelet execute
     *             impossible (e.g. missing required input data).
     */
    public int execute(PipelineDictionary dict) 
        throws PipeletExecutionException
    {        
        // lookup 'ProductLineItem' in pipeline dictionary
        ProductLineItem productLineItem = (ProductLineItem)dict.get(DN_PRODUCT_LINE_ITEM);
        if (null == productLineItem)
        {
            throw new PipeletExecutionException(
                            "Mandatory input parameter 'ProductLineItem' not available in pipeline dictionary.");
        }

        // lookup 'Cart' in pipeline dictionary
        Basket cart = (Basket)dict.get(DN_CART);
        if (null == cart)
        {
            throw new PipeletExecutionException(
                            "Mandatory input parameter 'cart' not available in pipeline dictionary.");
        }
        
        if(cart.getProductLineItemsCount() ==1)
        {
            return PIPELET_NEXT;
        }
        
        Iterator<ProductLineItem> lineItemsIterator = cart.createProductLineItemsOrderedByPositionIterator();
        String productSKU = productLineItem.getOfferProductRef().getProductSKU();
        Long storeId = (Long)productLineItem.getAttribute(storeFrontIdAttribute);
        String shippingMethodId = productLineItem.getShippingMethod().getId();
        String pliUUID = productLineItem.getUUID();

        while(lineItemsIterator.hasNext())
        {
            ProductLineItem currentLineItem = lineItemsIterator.next();
            
            if(currentLineItem.getUUID().equalsIgnoreCase(pliUUID)) 
            {
                continue;                
            }
            else 
            {
                if(storeId != null) 
                {
                    if(productSKU.equalsIgnoreCase(currentLineItem.getOfferProductRef().getProductSKU()) 
                                    && ((Long)currentLineItem.getAttribute(storeFrontIdAttribute)).equals(storeId) 
                                    && shippingMethodId.equalsIgnoreCase(currentLineItem.getShippingMethod().getId())) 
                    {
                        
                        BigDecimal quantity = currentLineItem.getQuantity().getValue();
                        Quantity quantity2 = new Quantity(productLineItem.getQuantity().getValue(), productLineItem.getQuantity().getUnit());
                        Quantity quantity3 = new Quantity(quantity2.getValue().add(quantity),productLineItem.getQuantity().getUnit());
                        
                        productLineItem.setQuantity(quantity3);
                        
                        basketMgr.removeProductLineItem(currentLineItem);
                        break;
                    }
                }
                else if(productSKU.equalsIgnoreCase(currentLineItem.getOfferProductRef().getProductSKU()) 
                                && "STD_GROUND".equalsIgnoreCase(shippingMethodId) 
                                && "STD_GROUND".equalsIgnoreCase(currentLineItem.getShippingMethod().getId())) 
                {
                    BigDecimal quantity = currentLineItem.getQuantity().getValue();
                    Quantity quantity2 = new Quantity(productLineItem.getQuantity().getValue(), productLineItem.getQuantity().getUnit());
                    Quantity quantity3 = new Quantity(quantity2.getValue().add(quantity),productLineItem.getQuantity().getUnit());
                    
                    productLineItem.setQuantity(quantity3);
                    
                    basketMgr.removeProductLineItem(currentLineItem);
                    break;
                }
            }
        }

        dict.put(DN_UPDATED_CART, cart);
        
        return PIPELET_NEXT;
    }
}